﻿#include "FormPicProc.h"
#include <QPushButton>
#include <QDropEvent>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QDebug>
#include "tools/cJSON.h"
#include "tools/util.h"
#include "design/styleDefine.h"

ImgLabel::ImgLabel(QWidget* parent)
    : QLabel(parent)
{
    // 支持文件拖拽到本区域
    setAcceptDrops(true);
    setAlignment(Qt::AlignCenter);
    setText("把图片直接拖进来吧(*^_^*)");
    setStyleSheet("background-color: #A8DADC;");
}

void ImgLabel::setFile(const QString& strFile)
{
    QImage pImgTemp;
    if(true == getImgFromPath(pImgTemp, strFile))
    {
        if(!pImgTemp.isNull())
        {
            m_ImgShow = pImgTemp;

            // 更新图片展示
            showImage(m_ImgShow);
        }
    }
}

bool ImgLabel::getCurImg(QImage& img)
{
    if (false == m_ImgShow.isNull())
    {
        img = m_ImgShow;
    }

    return (!m_ImgShow.isNull());
}

// 限制拖拽目标类型
void ImgLabel::dragEnterEvent(QDragEnterEvent* event)
{
    if(!event->mimeData()->urls()[0].fileName().right(3).compare("jpg") ||
       !event->mimeData()->urls()[0].fileName().right(3).compare("png") ||
       !event->mimeData()->urls()[0].fileName().right(3).compare("gif") )
    {
        event->acceptProposedAction();
    }
    else
    {
        event->ignore();
    }
}

// 接收图片拖拽输入后打开
void ImgLabel::dropEvent(QDropEvent* event)
{
    setFile(event->mimeData()->urls()[0].toLocalFile());
}

// 重置窗口大小
void ImgLabel::resizeEvent(QResizeEvent* event)
{
    if(nullptr != event)
    {
        showImage(m_ImgShow);
    }
}

// 刷新展示图片
void ImgLabel::showImage(QImage pImage)
{
    if (!pImage.isNull())
    {
        if (this->width() >= pImage.width() && this->height() >= pImage.height())
        {
            // 已有显示框大于图片原始大小，直接显示数据
            this->setPixmap(QPixmap::fromImage(pImage));
        }
        else
        {
            // 重新调整图片规格
            QSize pSize = this->size();
            pSize.setWidth(pSize.width() - 1);
            pSize.setHeight(pSize.height() - 1);
            QImage pImg = pImage.scaled(pSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
            this->setPixmap(QPixmap::fromImage(pImg));
        }

        emit sendImgInfo(pImage.width(), pImage.height(), "");
    }
}

/******************************************************************/
const uint nPicParamFixHeight = 200;
PicParam::PicParam(QWidget* parent)
    : QFrame(parent)
    , m_pColorDialog(nullptr)
{
    m_stImgInfo.clear();
    setFixedHeight(nPicParamFixHeight);
    m_pColorDialog = new QColorDialog();
    connect(m_pColorDialog, SIGNAL(colorSelected(const QColor&)), this, SLOT(slt_ColorSelected(const QColor)));
    
    auto getLabelObj = [&](const QString& strContext, const QString& strStyle) -> QLabel* {
        QLabel* pObj = new QLabel(this);
        pObj->setText(strContext);
        pObj->setFont(gFontConsolas);
        pObj->setStyleSheet(strStyle);
        pObj->setFixedHeight(25);
        pObj->setAlignment(Qt::AlignCenter);
        return pObj;
        };

    QHBoxLayout* pmainLayout = new QHBoxLayout;
    this->setLayout(pmainLayout);

    // 信息展示和基础配置
    QGroupBox* pGroupImgInfo = new QGroupBox(this);
    pmainLayout->addWidget(pGroupImgInfo);
    pGroupImgInfo->setTitle("图片信息");
    pGroupImgInfo->setFixedWidth(200);
    QFormLayout* pLayoutImgInfo = new QFormLayout;
    pGroupImgInfo->setLayout(pLayoutImgInfo);

    m_pImgHeight = getLabelObj("null", g_label2);
    m_pImgWidth = getLabelObj("null", g_label1);
    m_pLineWidth = new CustomSpinBoxInt(pGroupImgInfo);
    m_pLineWidth->setDefeat(5);
    m_pColor = new QPushButton(pGroupImgInfo);
    m_pColor->setFixedHeight(25);
    m_pColor->setStyleSheet("QPushButton { border: none; }");
    m_pColor->setFont(gFontConsolas);
    connect(m_pColor, SIGNAL(clicked()), this, SLOT(slt_OpenColorDialog()));
    m_pNormalize = new CustomCheckBoxList(pGroupImgInfo);
    pLayoutImgInfo->addRow(getLabelObj(" 图片宽度 ", g_label1), m_pImgWidth);
    pLayoutImgInfo->addRow(getLabelObj(" 图片高度 ", g_label2), m_pImgHeight);
    pLayoutImgInfo->addRow(getLabelObj(" 线条宽度 ", g_label1), m_pLineWidth);
    pLayoutImgInfo->addRow(getLabelObj(" 线条颜色 ", g_label2), m_pColor);
    pLayoutImgInfo->addRow(getLabelObj(" 数值归一 ", g_label1), m_pNormalize);

    m_pNormalize->addCheckOne("像素", "像素");
    m_pNormalize->addCheckOne("归一", "归一");
    m_pNormalize->setDefault(0);
    connect(m_pNormalize, SIGNAL(SendClickedIndex(uint)), this, SLOT(slt_NormalizeType(uint)));

    // 坐标参数输入
    QGroupBox* pGroupCoordinatePoint = new QGroupBox(this);
    pGroupCoordinatePoint->setTitle("坐标值/类型输入");
    pGroupCoordinatePoint->setFixedWidth(180);
    pmainLayout->addWidget(pGroupCoordinatePoint);

    QFormLayout* pLayoutCoordinatePoint = new QFormLayout;
    pGroupCoordinatePoint->setLayout(pLayoutCoordinatePoint);
    m_pLineInputXPoint = new QLineEdit(pGroupCoordinatePoint);
    m_pLineInputYPoint = new QLineEdit(pGroupCoordinatePoint);
    m_pLineInputWidth = new QLineEdit(pGroupCoordinatePoint);
    m_pLineInputHeight = new QLineEdit(pGroupCoordinatePoint);
    m_pLineInputXPoint->setAlignment(Qt::AlignHCenter);
    m_pLineInputYPoint->setAlignment(Qt::AlignHCenter);
    m_pLineInputWidth->setAlignment(Qt::AlignHCenter);
    m_pLineInputHeight->setAlignment(Qt::AlignHCenter);
    m_pLineInputXPoint->setFont(gFontConsolas);
    m_pLineInputYPoint->setFont(gFontConsolas);
    m_pLineInputWidth->setFont(gFontConsolas);
    m_pLineInputHeight->setFont(gFontConsolas);

    pLayoutCoordinatePoint->addRow(getLabelObj(" Ｘ点 ", g_label1), m_pLineInputXPoint);
    pLayoutCoordinatePoint->addRow(getLabelObj(" Ｙ点 ", g_label2), m_pLineInputYPoint);
    pLayoutCoordinatePoint->addRow(getLabelObj(" 宽度 ", g_label1), m_pLineInputWidth);
    pLayoutCoordinatePoint->addRow(getLabelObj(" 高度 ", g_label2), m_pLineInputHeight);

    m_pInputType = new CustomCheckBoxList(pGroupCoordinatePoint);
    pLayoutCoordinatePoint->addRow(getLabelObj(" 类型 ", g_label1), m_pInputType);
    m_pInputType->addCheckOne("坐标", "坐标");
    m_pInputType->addCheckOne("报文", "报文");
    m_pInputType->setDefault(0);
    connect(m_pInputType, SIGNAL(SendClickedIndex(uint)), this, SLOT(slt_InputType(uint)));
    m_pLineInputXPoint->setPlaceholderText("像素值");
    m_pLineInputYPoint->setPlaceholderText("像素值");
    m_pLineInputWidth->setPlaceholderText("像素值");
    m_pLineInputHeight->setPlaceholderText("像素值");

    // 坐标参数报文输入
    QGroupBox* pGroupCoordinateMsg = new QGroupBox(this);
    pGroupCoordinateMsg->setTitle("坐标报文输入");
    pmainLayout->addWidget(pGroupCoordinateMsg);

    QHBoxLayout* pMsgLayout = new QHBoxLayout;
    pGroupCoordinateMsg->setLayout(pMsgLayout);

    m_pMessageInput = new QTextEdit(pGroupCoordinateMsg);
    pMsgLayout->addWidget(m_pMessageInput);
    m_pMessageInput->setEnabled(false);
}

// 颜色选择更新
void PicParam::slt_ColorSelected(const QColor& color)
{
    m_pColor->setText(QString("R[%1] - G[%2] - B[%3]").arg(QString::number(color.red()), QString::number(color.green()), QString::number(color.blue())));
    m_pColor->setStyleSheet(QString("QPushButton{border: none; background-color:rgb(%1, %2, %3);}").arg(QString::number(color.red()),
        QString::number(color.green()),
        QString::number(color.blue())));
}

// 获取颜色值
void PicParam::slt_OpenColorDialog()
{
    if(nullptr != m_pColorDialog)
    {
        m_pColorDialog->exec();
    }
}

void PicParam::slt_NormalizeType(uint nIndex)
{
    //qDebug() << "slt_NormalizeType" << nIndex << this->rect();
    if (1 == m_pInputType->getSelectIndex())
    {
        return;
    }

    if (0 == nIndex)
    {
        m_pLineInputXPoint->setPlaceholderText("像素值");
        m_pLineInputYPoint->setPlaceholderText("像素值");
        m_pLineInputWidth->setPlaceholderText("像素值");
        m_pLineInputHeight->setPlaceholderText("像素值");
    }
    else
    {
        m_pLineInputXPoint->setPlaceholderText("归一化坐标");
        m_pLineInputYPoint->setPlaceholderText("归一化坐标");
        m_pLineInputWidth->setPlaceholderText("归一化坐标");
        m_pLineInputHeight->setPlaceholderText("归一化坐标");
    }
}
void PicParam::slt_InputType(uint nIndex)
{
    //qDebug() << "slt_InputType" << nIndex;
    if (0 == nIndex)
    {
        m_pMessageInput->setEnabled(false);
        slt_NormalizeType(m_pNormalize->getSelectIndex());
    }
    else
    {
        m_pMessageInput->setEnabled(true);
        m_pLineInputXPoint->setPlaceholderText("关键字");
        m_pLineInputYPoint->setPlaceholderText("关键字");
        m_pLineInputWidth->setPlaceholderText("关键字");
        m_pLineInputHeight->setPlaceholderText("关键字");
    }
}

void PicParam::slt_updateImgInfo(uint nWidth, uint nHeight, QString strType)
{
    m_stImgInfo.iWidth = nWidth;
    m_stImgInfo.iHeight = nHeight;
    m_stImgInfo.strFormat = strType;
    m_pImgWidth->setText(QString("%1 px").arg(m_stImgInfo.iWidth));
    m_pImgHeight->setText(QString("%1 px").arg(m_stImgInfo.iHeight));
}

bool PicParam::getPicParam(bool& bNormalize, uint &nLineSize, QVector<std::tuple<float, float, float, float>>& vecPoints)
{
    bool bRet = false;
    do
    {
        vecPoints.clear();
        bNormalize = (0 == m_pNormalize->getSelectIndex() ? true : false);
        nLineSize = m_pLineWidth->getCurValue();

        if (0 == m_pInputType->getSelectIndex())
        {
            // 单个坐标值
            if (m_pLineInputWidth->text().isEmpty() || m_pLineInputHeight->text().isEmpty() || m_pLineInputXPoint->text().isEmpty() || m_pLineInputYPoint->text().isEmpty())
            {
                // 所有输入存在空，报异常
                break;
            }

            vecPoints.push_back(std::make_tuple(m_pLineInputXPoint->text().toFloat(), m_pLineInputYPoint->text().toFloat(), m_pLineInputWidth->text().toFloat(), m_pLineInputHeight->text().toFloat()));
            // 根据归一化或具体数值判断输入值是否符合要求
            if (true == bNormalize)
            {
                if (std::get<0>(vecPoints[0]) >= 0 && std::get<0>(vecPoints[0]) <= 1.0 &&
                    std::get<1>(vecPoints[0]) >= 0 && std::get<1>(vecPoints[0]) <= 1.0 &&
                    std::get<2>(vecPoints[0]) >= 0 && std::get<2>(vecPoints[0]) <= 1.0 &&
                    std::get<3>(vecPoints[0]) >= 0 && std::get<3>(vecPoints[0]) <= 1.0)
                {
                    ;
                }
                else
                {
                    vecPoints.clear();
                    break;
                }
            }
            else
            {
                if (std::get<0>(vecPoints[0]) >= 0 && std::get<0>(vecPoints[0]) <= m_stImgInfo.iWidth &&
                    std::get<1>(vecPoints[0]) >= 0 && std::get<1>(vecPoints[0]) <= m_stImgInfo.iHeight &&
                    std::get<2>(vecPoints[0]) >= 0 && std::get<2>(vecPoints[0]) <= m_stImgInfo.iWidth &&
                    std::get<3>(vecPoints[0]) >= 0 && std::get<3>(vecPoints[0]) <= m_stImgInfo.iHeight)
                {
                    ;
                }
                else
                {
                    vecPoints.clear();
                    break;
                }
            }
        }
        else
        {
            // 报文输入方式

        }

        bRet = true;
    } while (0);

    return bRet;
}

static bool m_bShowPaintParams = false;

/******************************************************************/
FormPicProc::FormPicProc(QWidget* parent)
    : QFrame(parent)
    , m_pImgLabelShow(nullptr)
    , m_pPicParam(nullptr)
    , m_pAnimationImage(nullptr)
    , m_pAnimationParam(nullptr)
{
    this->setStyleSheet(PAGE_COMMON_SELECTED_COLOUR);

    m_pImgLabelShow = new ImgLabel(this);
    m_pPicParam = new PicParam(this);
    connect(m_pImgLabelShow, SIGNAL(sendImgInfo(uint, uint, QString)), m_pPicParam, SLOT(slt_updateImgInfo(uint, uint, QString)));

    // 工具栏
    m_pToolFrame = new QFrame(this);
    QHBoxLayout* pTools = new QHBoxLayout;
    pTools->setContentsMargins(WIDGET_CONTENTS_MARGINS, 0, WIDGET_CONTENTS_MARGINS, 0);
    m_pToolFrame->setLayout(pTools);
    m_pToolFrame->setFixedHeight(OBJ_FIXED_HEIGHT_NORMAL);

    QPushButton* pBtnOpenFile = NewPTBWithIcon(QString("打开"), QString("打开图片文件"), QIcon(QString(":/common/resource/common/file_open.ico")), this);
    QPushButton* pBtnSave = NewPTBWithIcon(QString("保存"), QString("保存已绘制图片到本地"), QIcon(QString(":/common/resource/common/file_save.ico")), this);
    QPushButton* pBtnBack = NewPTBWithIcon(QString("后退"), QString("后退到上一张图"), QIcon(QString(":/common/resource/common/back.ico")), this);
    QPushButton* pBtnNext = NewPTBWithIcon(QString("前进"), QString("前进到下一张图"), QIcon(QString(":/common/resource/common/next.ico")), this);
    QPushButton* pBtnParams = NewPTBWithIcon(QString("面板"), QString("打开或收起参数面板"), QIcon(QString(":/common/resource/common/opentradingnetwork.ico")), this);
    QPushButton* pBtnPaint = NewPTBWithIcon(QString("绘制"), QString("绘制"), QIcon(QString(":/common/resource/common/paint.ico")), this);
    
    connect(pBtnOpenFile, SIGNAL(clicked()), this, SLOT(slt_openFile()));
    connect(pBtnSave, SIGNAL(clicked()), this, SLOT(slt_save()));
    connect(pBtnBack, SIGNAL(clicked()), this, SLOT(slt_back()));
    connect(pBtnNext, SIGNAL(clicked()), this, SLOT(slt_next()));
    connect(pBtnParams, SIGNAL(clicked()), this, SLOT(slt_showPaintParams()));
    connect(pBtnPaint, SIGNAL(clicked()), this, SLOT(slt_paintWithParams()));

    pTools->addStretch();
    pTools->addWidget(pBtnOpenFile);
    pTools->addWidget(pBtnSave);
    pTools->addWidget(pBtnBack);
    pTools->addWidget(pBtnNext);
    pTools->addWidget(pBtnParams);
    pTools->addWidget(pBtnPaint);
    pTools->addStretch();

    m_pAnimationImage = new QPropertyAnimation(m_pImgLabelShow, "geometry");
    m_pAnimationImage->setDuration(ANIMATION_DURATION_TIME);
    m_pAnimationParam = new QPropertyAnimation(m_pPicParam, "geometry");
    m_pAnimationParam->setDuration(ANIMATION_DURATION_TIME);
}

// 打开文件
void FormPicProc::slt_openFile()
{
    const QString aFileName = GetFileFromFileDialog(this, QString("所有文件(*.*)"));
    if(aFileName.isEmpty())
    {
      //  myMessageBoxShowOne(m_eProcType, MSG_SHOW_ERROR, QString("未选择有效文件!"));
        return;
    }

    m_pImgLabelShow->setFile(aFileName);
}

// 保存文件
void FormPicProc::slt_save()
{

}

// 返回上一张图（如有）
void FormPicProc::slt_back()
{

}

// 跳到下一张图（如有）
void FormPicProc::slt_next()
{

}

// 绘制参数输入
void FormPicProc::slt_showPaintParams()
{
    m_bShowPaintParams = !m_bShowPaintParams;
    reshowAnimat(m_bShowPaintParams);
}

// 接收坐标参数并在图片上绘制
void FormPicProc::slt_paintWithParams()
{

}

void FormPicProc::reshow(const bool bShow)
{
    const uint nWidgetWidth = this->size().width() - 2 * WIDGET_SPACINGS_LEN;
    if (true == bShow)
    {
        const uint nImgHeiht = this->size().height() - 4 * WIDGET_SPACINGS_LEN - OBJ_FIXED_HEIGHT_NORMAL - nPicParamFixHeight;
        if (nullptr != m_pImgLabelShow)
        {
            m_pImgLabelShow->setGeometry(WIDGET_SPACINGS_LEN, WIDGET_SPACINGS_LEN, nWidgetWidth, nImgHeiht);
        }

        if(nullptr != m_pPicParam)
        {
            m_pPicParam->setGeometry(WIDGET_SPACINGS_LEN, WIDGET_SPACINGS_LEN * 2 + nImgHeiht, nWidgetWidth, nPicParamFixHeight);
        }

        m_pToolFrame->setGeometry(WIDGET_SPACINGS_LEN, WIDGET_SPACINGS_LEN * 3 + nImgHeiht + nPicParamFixHeight, nWidgetWidth, OBJ_FIXED_HEIGHT_NORMAL);
    }
    else
    {
        const uint nImgHeiht = this->size().height() - 3 * WIDGET_SPACINGS_LEN - OBJ_FIXED_HEIGHT_NORMAL;
        if (nullptr != m_pImgLabelShow)
        {
            m_pImgLabelShow->setGeometry(WIDGET_SPACINGS_LEN, WIDGET_SPACINGS_LEN, nWidgetWidth, nImgHeiht);
        }

        if(nullptr != m_pPicParam)
        {
            m_pPicParam->setGeometry(WIDGET_SPACINGS_LEN, this->size().height() - WIDGET_SPACINGS_LEN, this->size().width() - 2 * WIDGET_SPACINGS_LEN, 0);
        }

        m_pToolFrame->setGeometry(WIDGET_SPACINGS_LEN, WIDGET_SPACINGS_LEN * 2 + nImgHeiht, nWidgetWidth, OBJ_FIXED_HEIGHT_NORMAL);
    }
}

void FormPicProc::reshowAnimat(const bool bShow)
{
    const uint nWidgetWidth = this->size().width() - 2 * WIDGET_SPACINGS_LEN;
    m_pAnimationImage->setStartValue(m_pImgLabelShow->geometry());
    m_pAnimationParam->setStartValue(m_pPicParam->geometry());
    if (true == bShow)
    {
        m_pAnimationImage->setEndValue(QRect(WIDGET_SPACINGS_LEN, WIDGET_SPACINGS_LEN, nWidgetWidth, this->size().height() - 4 * WIDGET_SPACINGS_LEN - OBJ_FIXED_HEIGHT_NORMAL - nPicParamFixHeight));
        m_pAnimationParam->setEndValue(QRect(WIDGET_SPACINGS_LEN, this->size().height() - 2 * WIDGET_SPACINGS_LEN - OBJ_FIXED_HEIGHT_NORMAL - nPicParamFixHeight, nWidgetWidth, nPicParamFixHeight));
    }
    else
    {
        m_pAnimationImage->setEndValue(QRect(WIDGET_SPACINGS_LEN, WIDGET_SPACINGS_LEN, nWidgetWidth, this->size().height() - 3 * WIDGET_SPACINGS_LEN - OBJ_FIXED_HEIGHT_NORMAL));
        m_pAnimationParam->setEndValue(QRect(WIDGET_SPACINGS_LEN, this->size().height(), nWidgetWidth, 0));// 直接将参数界面移除到界面之外
    }

    m_pToolFrame->setGeometry(WIDGET_SPACINGS_LEN, this->size().height() - WIDGET_SPACINGS_LEN - OBJ_FIXED_HEIGHT_NORMAL, nWidgetWidth, OBJ_FIXED_HEIGHT_NORMAL);

    m_pAnimationImage->start();
    m_pAnimationParam->start();
}

void FormPicProc::resizeEvent(QResizeEvent* event)
{
    reshow(m_bShowPaintParams);
}